﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Text.RegularExpressions;

namespace Ruandao.MiniFace
{
    public class Segment
    {
        public bool IsTarget { get; set; }

        public string Text { get; set; }


        public Segment(bool isTarget, string text)
        {
            this.IsTarget = isTarget;
            this.Text = text;
        }

    }

    public class SegmentEnumerator : IEnumerator<Segment>
    {
        IEnumerator matchEnumerator;
        int segmentStart = 0;   // 当前项的开始索引。
        int segmentLength = 0;  // 当前项的长度。
        bool isTarget = true;   // 当前项是否是匹配项。开始时，要设为true, 因为next要执行下一个目标匹配。
        string htmlText ;       // 整个需要遍历的文本。

        public SegmentEnumerator(string htmlText, string pattern)
        {
            this.htmlText = htmlText;
            matchEnumerator =  Regex.Matches(htmlText, pattern, RegexOptions.Singleline).GetEnumerator();
        }

        public Segment Current
        {
            get { return GetCurrent(); }
        }

        public void Dispose()
        {

        }

        object IEnumerator.Current
        {
            get 
            {
                return GetCurrent();
            }
        }

        private Segment GetCurrent()
        {
            if (segmentLength == 0) throw new InvalidOperationException();
            string text = htmlText.Substring(segmentStart, segmentLength);
            return new Segment(isTarget, text);
        }

        public bool MoveNext()
        {
            // 如果当前项不是匹配项，那么下一项一定是匹配项，否则就是下一项不存在了（即当前项已经到达末尾）。
            if (isTarget == false) 
            {
                segmentStart += segmentLength;
                if (segmentStart == htmlText.Length) // 已经是末尾。
                {
                    segmentLength = 0;
                    return false;
                }
                segmentLength = ((Match)(matchEnumerator.Current)).Length;
                isTarget = true;
                return true;
            }

            // 二、下面的情况是当前项是匹配项，那么下一项就需要继续匹配来获取了。

            // 1. 当前项是匹配项，而且没有查到下一个匹配项，那么只可能是已经到达末尾，或者还末尾之前的最后一个非匹配项。
            if(!matchEnumerator.MoveNext())
            {
                segmentStart += segmentLength;
                if (segmentStart == htmlText.Length ) // 已经是末尾。
                {
                    segmentLength = 0;
                    return false;
                }
                    
                segmentLength = htmlText.Length - segmentStart;
                isTarget = false;
                return true;
            }
            // 2. 当前项是匹配项，而且找到下一个匹配项，那么执行下边的代码：
            segmentStart += segmentLength;
            segmentLength = ((Match)(matchEnumerator.Current)).Index - segmentStart;
            isTarget = false;
            if ( segmentLength == 0 ) // 当前匹配项和下一个匹配项之间没有字符。
            {
                isTarget = true;
                segmentLength = ((Match)(matchEnumerator.Current)).Length;
            }
            return true;
        }

        public void Reset()
        {
            throw new NotImplementedException();
        }
    }

    public class Traversal
        : IEnumerable<Segment>
    {
        string htmlText;
        string pattern;

        public Traversal(string htmlText, string pattern)
        {
            this.htmlText = htmlText;
            this.pattern = pattern;
        }

        public IEnumerator<Segment> GetEnumerator()
        {
            return new SegmentEnumerator(htmlText, pattern);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new SegmentEnumerator(htmlText, pattern);
        }
    }
}
